package fr.mywiki.business.wiki.render.filter;


import org.jdom.Element;
import org.radeox.filter.CacheFilter;
import org.radeox.filter.context.FilterContext;
import org.radeox.filter.regex.LocaleRegexTokenFilter;
import org.radeox.filter.regex.RegexTokenFilter;
import org.radeox.regex.MatchResult;

import fr.mywiki.business.entry.EntryLite;
import fr.mywiki.business.search.SearchEntryManager;
import fr.mywiki.business.xml.XmlManager;

/**
 * Implementation of the internal link filter: <code>wikilink</code>.
 * 
 * @author tlombard
 */
public class WikilinkFilter extends LocaleRegexTokenFilter implements
		CacheFilter {
	/* The style classes */
	private static final String FOUND_LINK_CLASS = "foundlink";
	private static final String NOT_FOUND_LINK_CLASS = "notfoundlink";
	private static final String EXT_URL_CLASS = "externurl";
	
	/** Url pattern */
	private static final String URL_PATTERN = "([^\"'=]|^)((http|ftp)s?://(%[\\p{Digit}A-Fa-f][\\p{Digit}A-Fa-f]|[-_.!~*';/?:@#&=+$,\\p{Alnum}])+)";
	
	protected String getLocaleKey() {
		return "filter.wikilink";
	}

	/**
	 * <p>
	 * Method called for every occurence of the regular expression
	 * "filter.wiklink.match". The buffer is concatened with a url computed here
	 * from the match result.
	 * </p>
	 * <p>
	 * The way to compute the url is to search for a <code>EntryLite</code>
	 * object whose title would be near enough of the term between [[ and ]]
	 * (i.e. whose intern title would be equal).
	 * </p>
	 * 
	 * @param buffer Buffer to write replacement string to
	 * @param matchResult Hit with the found regular expression
	 * @param context FilterContext for filters
	 * 
	 * @see RegexTokenFilter#handleMatch(java.lang.StringBuffer,
	 *      org.radeox.regex.MatchResult,
	 *      org.radeox.filter.context.FilterContext)
	 * FIXME [[Title]] ne fonctionne pas bien.
	 */
	public void handleMatch(StringBuffer buffer, MatchResult matchResult,
			FilterContext context) {
		// Get the complete matched pattern
		String pattern = matchResult.group(1);
		
		// Parts of the rebuilt URL
		String linked = new String();
		String title = new String();
		String displayed = pattern;
		String style = new String();
		
		Element anchor = new Element("a");
		
		// Check whether there is a '|' (two parts)
		int sepIndex = pattern.indexOf('|');
		if (sepIndex >= 1 && sepIndex < pattern.length() - 1) {
			// First part is the title
			title = pattern.substring(0, sepIndex);
			// Secund part is what is displayed
			displayed = pattern.substring(sepIndex+1);
		}
		
		if (title.matches(URL_PATTERN)) {
			// A url has been detected
			linked = title;
			style = EXT_URL_CLASS;
		} else {
			// The title being given, search the entry corresponding to it.
			EntryLite entry = SearchEntryManager.searchExactTitle(title);

			if (entry == null) {
				// No entry found
				linked = "javascript:createEntry('" + title + "');";
				style = NOT_FOUND_LINK_CLASS;
			} else {
				// An entry was found
				linked = "javascript:seeEntry('" + entry.getId() + "');";
				style = FOUND_LINK_CLASS;
			}
		}
		
		anchor.addAttribute("href",linked);
		anchor.addAttribute("class",style);
		anchor.setText(displayed);
		
		buffer.append(XmlManager.XmlToString(anchor).replaceAll("&apos;","'"));
	}
}
